package org.internna.ossmoney.model;

import java.util.Locale;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import javax.persistence.OneToOne;
import javax.persistence.ManyToOne;
import javax.persistence.FetchType;
import javax.persistence.CascadeType;
import javax.validation.constraints.NotNull;
import org.internna.ossmoney.model.Investment;
import org.internna.ossmoney.model.InvestmentPrice;
import org.internna.ossmoney.model.AccountTransaction;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.roo.addon.tostring.RooToString;
import org.springframework.roo.addon.jpa.entity.RooJpaEntity;
import org.springframework.roo.addon.serializable.RooSerializable;
import org.springframework.roo.addon.jpa.activerecord.RooJpaActiveRecord;

@RooJavaBean
@RooJpaEntity
@RooSerializable
@RooJpaActiveRecord
@RooToString(excludeFields = {"investment", "accountTransaction"})
public class InvestmentTransaction extends AbstractEntity implements Comparable<InvestmentTransaction> {

    private static final long serialVersionUID = -1710690949437766818L;

    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    private Investment investment;

    @NotNull
    @OneToOne(fetch = FetchType.LAZY)
    private AccountTransaction accountTransaction;

    @NotNull
    private Double quantity;

    @OneToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
    private InvestmentPrice price;

	@Override public final int compareTo(InvestmentTransaction other) {
		return other == null ? -1 : other.accountTransaction == null ? -1 : accountTransaction == null ? 1 : accountTransaction.compareTo(other.accountTransaction);
	}

	public String getAsJSONString() {
		Locale locale = accountTransaction.getAccount().getLocale();
		String subcat = accountTransaction.getSubcategory().getCategory();
		Double amount = accountTransaction.getAmount().abs().doubleValue();
		NumberFormat nFormatter = NumberFormat.getNumberInstance(locale);
		NumberFormat cFormatter = NumberFormat.getCurrencyInstance(locale);
		DateFormat dFormatter = new SimpleDateFormat("yyyy-MM-dd", locale);
		StringBuilder builder = new StringBuilder("{id: 9999")
			.append(getId()).append(", label: '', buy: '")
			.append(formatAmount(cFormatter, "category.investment.buy".equals(subcat) ? amount : 0D))
			.append("', sell: '").append(formatAmount(cFormatter, "category.investment.sell".equals(subcat) ? amount : 0D))
			.append("', interest: '").append(formatAmount(cFormatter, "category.investment.interest".equals(subcat) ? amount : 0D))
			.append("', quantity: '").append(quantity > 0D ? nFormatter.format(quantity) : "").append("', price: '").append(formatAmount(cFormatter, price == null ? 0D : price.getPrice()))
			.append("', gainLoss: ''").append(", pctg: '', quant: ").append(quantity).append(", operationDate: '")
			.append(dFormatter.format(accountTransaction.getOperationDate())).append("'}");
		return builder.toString();
	}

	protected String formatAmount(final NumberFormat formatter, final Double amount) {
		return amount == null || amount == 0D ? "" : formatter.format(amount.doubleValue());
	}

}
